/*
 *  
    Copyright (C) 2008  Nathaniel Waisbrot

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package termint.brains;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import termint.game.Alignment;
import termint.gui.vt.VT320;
import termint.gui.vt.VTChangeEvent;
import termint.gui.vt.VTChangeListener;

/**
 * Watches the status line.  The watches can take listeners who need updates, but it can also
 * just be used as the source of info about the current stats
 * @author Nathaniel Waisbrot
 *
 */
public class StatsWatcher implements VTChangeListener {
	final Logger log = LoggerFactory.getLogger(getClass());
	int dlvl;
	final Map<String,Integer> attr = new HashMap<>();
	{
		for (String s : new String[]{"St","Dx","Co","In","Wi","Ch"}) {
			attr.put(s, -1);
		}
	}
	Alignment.Type align;
	final ArrayList<StatsListener> listeners = new ArrayList<StatsListener>(); 
	
	public StatsWatcher(VT320 vt) {
		vt.addVTChangeListener(this);
	}
	
	private static final int l1 = 22;
	private static final int l2 = 23;
	private static final Pattern l1regex = Pattern.compile("(\\w+) the (.*?)\\s+St:(\\d+)(?:/\\d+)? Dx:(\\d+) Co:(\\d+) In:(\\d+) Wi:(\\d+) Ch:(\\d+)\\s+(Chaotic|Lawful|Neutral)\\s*");
	private static final Pattern l2regex = Pattern.compile("Dlvl:(\\d+)\\s+[$]:(\\d+) +HP:(\\d+)[(](\\d+)[)] +Pw:(\\d+)[(](\\d+)[)] +AC:(\\d+) +Exp:(\\d+) +T:(\\d+)\\s*");
	public void VTChanged(VTChangeEvent event) {
		VT320 vt = event.getSource();
		// a change to the stat line
		if (event.getChanges()[l1]) {
			if (vt.isEmptyRow(l1))
				return;
			if (vt.getCursorRow() >= l1)
				return;
			String changedLine = String.valueOf(vt.getRow(l1));
			String[] segments = changedLine.split("\\s+");
			for (int i = 3; i < segments.length; i++) {
				String segment = segments[i];
				if (segment.length() < 4)
					continue;
				String key = segment.substring(0, 2);
				Integer val = attr.get(key);
				if (val != null) {
					String valString1 = segment.substring(3);
					String valString2 = valString1.substring(0, Math.min(2, valString1.length()));
					Integer val2 = Integer.valueOf(valString2);
					attr.put(key, val2);
				}
			}
		}  
		if (event.getChanges()[l2]) {
			if (vt.isEmptyRow(l2))
				return;
			String changedLine = String.valueOf(vt.getRow(l2));
			String[] segments = changedLine.split("\\s+");
			for (String segment : segments) {
				if (segment.startsWith("Dlvl")) {
					int dlvl;
					try {
						dlvl = Integer.parseInt(segment.substring(5));
					} catch (NumberFormatException e) {
						return;
					}
					if (dlvl != this.dlvl) {
						this.dlvl = dlvl;
						for (StatsListener l : listeners)
							l.dungeonLevel(dlvl);
					}
				}
			}
		}
	}

	public void addListener(StatsListener listener) {
		if (!listeners.contains(listener)) {
			listeners.add(listener);
		}
	}
	
	public int dlvl() {
		return dlvl;
	}

	public int cha() {
		return attr.get("Ch");
	}
}
